package org.web2024.service.serviceimp;
import com.opencsv.CSVParser;
import com.opencsv.bean.CsvToBeanBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.web2024.cnofig.CourseSelectionConfig;
import org.web2024.dao.*;
import org.web2024.mapper.AdminMapper;
import org.web2024.mapper.StudentMapper;
import org.web2024.utils.CaculateUtil;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Objects;

import org.web2024.mapper.TeacherMapper;

@Service
public class AdminService {
    @Autowired
    private CourseSelectionConfig courseSelectionConfig;

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private TeacherMapper TeacherMapper;

    @Autowired
    private CourseService courseService;

    @Transactional(rollbackFor = Exception.class)
    public void ChangeSelectTime(String newStartTime,String newEndTime){
        courseSelectionConfig.setEndTime(newEndTime);
        courseSelectionConfig.setStartTime(newStartTime);
    }

    @Transactional(rollbackFor = Exception.class)
    public Result enableTerm(String term,String startTime,String endTime){
        if(adminMapper.termIsSelected(term)==1){
            return Result.fail("该学期已选课");
        }
        HashMap<String,Object> data=new HashMap<>();
        data.put("term",term);
        data.put("starttime",startTime);
        data.put("endtime",endTime);
        redisTemplate.opsForHash().putAll("currentterm",data);
        List<String> snoList=studentMapper.selectAllsno();
        try{
            redisTemplate.executeWithStickyConnection(connection -> {
                snoList.forEach(sno -> {
                    redisTemplate.opsForHash().put("student:" + sno, "coins", 100);
                });
                return null;
            });
        }catch (Exception e){
            return Result.fail("学生初始化失败");
        }
        return Result.success();
    }

    public Result Courseser(){
        if(redisTemplate.opsForHash().get("currentterm","termname")==null){
            return Result.fail("请先开启选课");
        }
        try{
            courseService.CourseSer();
        }catch (Exception e){
            return Result.fail("选课结果处理失败");
        }
        return Result.success();
    }

    public Result addterm(String term){
        if(!CaculateUtil.isValidSemester(term)){
            return Result.fail("学期格式不正确");
        }
        int score = CaculateUtil.getTermScore(term);
        if(term.equals(adminMapper.getTerm(term))){
            return Result.fail("该学期已存在");
        }
        adminMapper.addTerm(term,score);
        redisTemplate.delete("terms");
        return Result.success();
    }
    public Result coursefile(MultipartFile coursefile){
        try (// 使用try-with-resources确保输入流和缓冲读取器在使用后正确关闭
             InputStream inputStream = coursefile.getInputStream();
             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("GBK")))) {
            // 使用CsvToBeanBuilder将CSV数据转换为Course对象列表
            List<Course> courses = new CsvToBeanBuilder<Course>(bufferedReader)
                    .withType(Course.class)
                    .withSeparator(CSVParser.DEFAULT_SEPARATOR)
                    .withIgnoreLeadingWhiteSpace(true)
                    .build()
                    .parse();
            adminMapper.addCourseList(courses);
            // 使用Redis管道批量将Course对象存储到Redis中，以提高效率
            redisTemplate.executePipelined((RedisCallback<Object>)connection -> {
                for (Course course : courses) {
                    String key = "course:".concat(course.getC_no());
                    redisTemplate.opsForValue().set(key,course);
                }
                return null;
            });
            // 返回成功结果
            return Result.success();
        } catch (IOException e) {
            // 处理异常或记录日志
            throw new RuntimeException("读取CSV文件时发生错误", e);
        }
    }


    public List<Student> showAllStudent(){
        return studentMapper.showAllStudent();
    }

    public Result studentfile(MultipartFile studentfile) {
        try {
            InputStream inputStream = studentfile.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,Charset.forName("GBK")));
            List<Student> students = new CsvToBeanBuilder<Student>(bufferedReader)
                    .withType(Student.class)
                    .withSeparator(CSVParser.DEFAULT_SEPARATOR)
                    .withIgnoreLeadingWhiteSpace(true)
                    .build()
                    .parse();
            List<User>users=new ArrayList<>();
            students.forEach(student -> {
                users.add(new User(null,student.getS_no(),passwordEncoder.encode(student.getS_no())));
            });
            adminMapper.addStudentList(students);
            adminMapper.addUserList(users);
        }catch (IOException e){
            return Result.fail("文件读取失败");
        }
        return Result.success("文件读取成功");
    }

    public Result teacherfile(MultipartFile studentfile){
        try {
            InputStream inputStream = studentfile.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,Charset.forName("GBK")));
            List<Teachar> teacher = new CsvToBeanBuilder<Teachar>(bufferedReader)
                    .withType(Teachar.class)
                    .withSeparator(CSVParser.DEFAULT_SEPARATOR)
                    .withIgnoreLeadingWhiteSpace(true)
                    .build()
                    .parse();
            List<User>users=new ArrayList<>();
            teacher.forEach(teachar -> {
                users.add(new User(null,teachar.getT_no(),passwordEncoder.encode(teachar.getT_no())));
            });
            adminMapper.addTeacherList(teacher);
            adminMapper.addUserList(users);
        }catch (IOException e){
            return Result.fail("文件读取失败");
        }
        return Result.success("文件读取成功");
    }





    public Student showStudentInfo(Student student){
        String s_no=student.getS_no();
        System.out.println(s_no);
        return studentMapper.showStudentInfo(s_no);
    }
    public boolean admModifyStuInfo(Student student){
        return studentMapper.admModifyStuInfo(student);

    }
    public Teachar showTeaInfo(Teachar teacher){
        String t_no=teacher.getT_no();
        return TeacherMapper.showTeaInfo(t_no);
    }
    public boolean admModifyTeaInfo(Teachar teacher){
        return TeacherMapper.admModifyTeaInfo(teacher);
    }
    public List<Course> stuCourseInfo(HashMap<String,String>data){;
        return studentMapper.stuCourseInfo(data);
    }
    public List<Course> teaCourseInfo(HashMap<String,String>data){
        return TeacherMapper.teaCourseInfo(data);
    }
    public Course showCourseInfo(String cNo){
        return adminMapper.showCourseInfo(cNo);
    }
    public List<Student> showCourseStudents(String cNo){
        return adminMapper.showCourseStudents(cNo);
    }
    public boolean modifyCourseInfo(Course course){
        String c_no=course.getC_no();
        List<Course> courses = adminMapper.showAllCourse();
        for (Course C : courses){
            if (Objects.equals(C.getC_start_time(), course.getC_start_time())){
                if (!Objects.equals(C.getC_no(), c_no)){
                    if (Objects.equals(C.getC_time(), course.getC_time()) && Objects.equals(C.getC_address(), course.getC_address())){
                        return false;
                    }
                }
            }
        }
        if(course.getC_no()!=null&&redisTemplate.hasKey("course"+course.getC_no())){
            redisTemplate.opsForValue().set("course"+course.getC_no(),course);
        }
        adminMapper.modifyCourseInfo(course);
        return true;
    }
   public boolean deleteCourse(String c_no){
        adminMapper.delCourse(c_no);
        adminMapper.delscBycno(c_no);
        return true;
   }
   public boolean deleteStudent(String s_no){
        adminMapper.delStudent(s_no);
        adminMapper.delscBysno(s_no);
        return true;
   }
}
